<template>
	<view class="paint-box">
		<view class="box-header">
			<view class="header-icon">GoEasy示例</view>
			<view class="header-description">Websocket 远程画板</view>
		</view>
		<view class="box-body" id="canvasdiv">
			<view v-show="ready" class="canvasBox">
				<canvas
					canvas-id="canvas"
					style="width:346px;height:408px;"
					:disable-scroll="true"
					@touchstart="onDraw($event,'start')"
					@touchmove="onDraw($event,'move')"
					@touchend="onDraw($event,'end')"
				></canvas>
			</view>
			<view v-show="!ready" class="loading"></view>
		</view>
		<view class="box-bottom">
			<view
				id="pencil"
                @click="selectProp('pencil')"
				:class="currentProp === 'pencil' ? 'pencil_checked' : 'pencil'">
			</view>


			<img
				v-for="(item,index) in colors"
				:src="currentColor === item.color ? item.src : item.checkedSrc"
				:id="item.id"
				@click="switchColor(item.color)"
				:class="currentColor === item.color ? 'color_checked':'color_img'"/>



			<view class="line"></view>
			<view
				id="eraser"
				@click="selectProp('eraser')"
				:class="currentProp === 'eraser' ? 'eraser_checked' : 'eraser'">
			</view>
		</view>
		
	</view>
</template>

<script>
export default {
	data() {
		return {

			colors : [
				{id: "red", color: "#D02129", src: '../../static/red_color.png', checkedSrc:'../../static/red_color_checked.png'},
				{id: "yellow", color: "#FFC107", src:"../../static/yellow_color.png", checkedSrc:"../../static/yellow_color_checked.png"},
				{id: "green", color: "#1BB723", src:"../../static/green_color.png", checkedSrc:"../../static/green_color_checked.png"},
				{id: "violet", color: "#9D27B0", src:"../../static/violet_color.png", checkedSrc:"../../static/violet_color_checked.png"},
				{id: "blank", color: "#000000", src:"../../static/blank_color.png", checkedSrc:"../../static/blank_color_checked.png"},
			],

            props: [
                'pencil',
                'eraser'
            ],


            ready: false,

            canvasContext: '',

            currentColor: "#D02129",

			currentProp: 'pencil',

            currentUserId: 'user-' + Date.now(),



			//不要每个点都发送，做短期的堆积，可以在性能和效果间取得平衡
            buffer: {
                maxTime: 1000, //最多堆积时间毫秒数
                startTime: 0,
                points: [],

                //先缓冲
                push: function (point) {
                    if (this.points.length === 0) {
                        this.startTime = Date.now();
                    }
                    this.points.push(point);
                },

                //是否超出缓冲时间
                overflow() {
                    let now = Date.now();
                    let bufferedTime = now - this.startTime;
                    return bufferedTime >= this.maxTime;
                },

                //返回所有
                pop: function () {
                    let bufferLength = this.points.length;
                    return this.points.splice(0, bufferLength);
                }
            }

		}
	},

    onLoad() {
        this.goEasy.connect({
            id: this.currentUserId,
            onSuccess: function(){
                console.log("Connect success");
            },
            onFailed: function(e){
                console.log("Connect failed:"+ JSON.stringify(e));
            },
            onProgress: function(i){
                console.log("Connecting: ", i);
            }
        });


		//监听直播信号
		this.goEasy.pubsub.subscribe({
			channel: "remote-paint",
			onMessage: (message) => {

				let data = JSON.parse(message.content);

				//如果是自己的动作，就忽略
				if (data.senderId === this.currentUserId) {
					return;
				}

				data.line.forEach(point => {
					this.drawLocally(data.prop, data.color, point);
				})
			},
			onSuccess: () => {
				this.ready = true;
				console.log('subscribe success');
			},
			onFailed: (error) => {
				console.log("error", error)
			}
		});

    },
	created() {
		this.canvasContext = uni.createCanvasContext('canvas',this);
		this.canvasContext.lineWidth= 3;

	},

	methods: {


        switchColor (color) {
            this.currentColor = color;
            this.selectProp('pencil');
        },
        selectProp (prop) {
            this.currentProp = prop;
        },


        //监听画笔动作
        onDraw(event, action) {

            let point = {
                action: action,
                x: event.changedTouches[0].x,
                y: event.changedTouches[0].y
            };

            //本地绘制
            this.drawLocally(this.currentProp, this.currentColor, point);

            //直播画笔轨迹
            this.live(point);
        },


        //本地绘制
		drawLocally(prop, color, point) {
            if (prop === "pencil") {
                if (point.action === 'start') {
                    this.canvasContext.setStrokeStyle(color);
                    this.canvasContext.beginPath();
                    this.canvasContext.moveTo(point.x, point.y);
                    this.canvasContext.stroke();
                    this.canvasContext.draw(true);
                }
                if (point.action === 'move') {
                    this.canvasContext.lineTo(point.x, point.y);
                    this.canvasContext.stroke();
                    this.canvasContext.draw(true);
                    this.canvasContext.moveTo(point.x, point.y);
                }
            }

            if (prop === "eraser") {
                this.canvasContext.clearRect(point.x, point.y, 20, 20);
                this.canvasContext.draw(true);
            }
		},

        //直播画笔轨迹
        live: function (point) {

            //先缓冲
            this.buffer.push(point);

            //当超出缓冲时间，或一笔结束的时候，播放数据
            if (this.buffer.overflow() || point.action === 'end') {
                let points = this.buffer.pop();
                this.sendMessage(points);
            } else {
                console.log("caching...");
            }
        },

        //发送消息
        sendMessage: function (points) {
            if (points.length > 0) {
                let message = {
                    senderId: this.currentUserId,
                    prop: this.currentProp,
                    color: this.currentColor,
                    line: points
                };

				let x = JSON.stringify(message);

				try{
					this.goEasy.pubsub.publish({
						channel: "remote-paint",
						message: x,
						onSuccess: function () {
							console.log("publish success.");
						},
						onFailed: function (e) {
							console.log("message", JSON.stringify(message));
							console.log("Failed to publish:", JSON.stringify(e));
						},
					});
				}catch (e) {
					// console.log("message", x);
					console.log("message.size", x.length);
					console.log("error", e);
				}

            }
        }


    }
}
</script>

<style style="less" scoped>
html, body {
	padding: 0 0 0 0;
	margin: 0 0 0 0;
	background: #FFFFFF;
	height: 100%;
	width: 100%;
	font-family: 'HanHei SC', PingHei, 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft Yahei', 'Hiragino Sans GB', 'Heiti SC', 'WenQuanYi Micro Hei', sans-serif;
}
.paint-box {
	width: 100%;
	height: 100%;
	display: flex;
	flex-direction: column;
	position: relative;
}
.box-header {
	margin-top: 50px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: space-around;
	border-bottom: 1px solid #dddddd;
}
.header-icon {
	font-size: 28px;
	font-weight: bold;
	color: #D02129;
}
.header-description {
	font-size: 18px;
	margin: 10px 0;
}
.loading {
	width: 50px;
	height: 50px;
	background: url(../../static/loading.gif) no-repeat center center;
}
.box-body {
	flex: 1;
	width: 100%;
	display: flex;
	align-items: center;
	flex-direction: column;
	justify-content: center;
}
.canvasBox {
	box-shadow: 0 6px 26px rgba(0,0,0,.3);
	width: 346px;
	height: 408px;
/* 	display: flex;
	align-items: center;
	flex-direction: column;
	justify-content: center; */
}

.box-bottom {
	display: flex;
	align-items: center;
	width: 100%;
	height: 64px;
	background: #EBECED;
	justify-content: space-around;
	
}
.pencil {
	width: 32px;
	height: 32px;
	background: url(../../static/pencil.png) no-repeat center center;
}
.pencil_checked {
	width: 32px;
	height: 32px;
	background: url(../../static/pencil_checked.png) no-repeat center center;
}
.eraser {
	width: 32px;
	height: 32px;
	background: url(../../static/eraser.png) no-repeat center center;
}
.eraser_checked {
	width: 32px;
	height: 32px;
	background: url(../../static/eraser_checked.png) no-repeat center center;
}
.color_img {
	width: 25px;
	height: 25px;
}
.color_checked {
	width: 36px;
	height: 36px;
}
.line {
	width: 1px;
	height: 33px;
	background: #C4C4C4;
}
</style>
